package com.ruoyi.system.service.impl;

import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.entity.WxUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.mapper.WxUserMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 微信用户Service业务层处理
 *
 * @author yuanzheng
 * @date 2021-12-25
 */
@Service
public class WxUserServiceImpl implements IWxUserService {
    @Autowired
    private WxUserMapper wxUserMapper;

    @Resource
    private ISysUserService sysUserService;

    @Resource
    private ISysDeptService sysDeptService;


    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysMenuService menuService;

    // 令牌有效期（默认30分钟）
    @Value("${token.expireTime}")
    private int expireTime;

    protected static final long MILLIS_SECOND = 1000;
    protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND;


    /**
     * 查询微信用户
     *
     * @param id 微信用户ID
     * @return 微信用户
     */
    @Override
    public WxUser selectWxUserById(String id) {
        return wxUserMapper.selectWxUserById(id);
    }


    @Override
    public WxUser selectWxUserByOpenId(String openId) {
//        return wxUserMapper.selectWxUserByOpenId(openId);
        List<WxUser> list = wxUserMapper.selectWxUserListByOpenId(openId);
        if(list != null && list.size() > 0){
            return list.get(0);
        }
        return null;
    }


    /**
     * 查询微信用户列表
     *
     * @param wxUser 微信用户
     * @return 微信用户
     */
    @Override
    public List<WxUser> selectWxUserList(WxUser wxUser) {
        return wxUserMapper.selectWxUserList(wxUser);
    }

    /**
     * 新增微信用户
     *
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public int insertWxUser(WxUser wxUser) {
        if(StringUtils.isBlank(wxUser.getId())){
            wxUser.setId(IdUtils.fastSimpleUUID());
        }
        wxUser.setCreateBy(SecurityUtils.getUsername());
        wxUser.setCreateTime(DateUtils.getNowDate());
        return wxUserMapper.insertWxUser(wxUser);
    }

    @Override
    public int insertWxUserNoToken(WxUser wxUser) {
        if(StringUtils.isBlank(wxUser.getId())){
            wxUser.setId(IdUtils.fastSimpleUUID());
        }
        wxUser.setCreateBy(wxUser.getOpenId());
        wxUser.setCreateTime(DateUtils.getNowDate());
        return wxUserMapper.insertWxUser(wxUser);
    }

    /**
     * 修改微信用户
     *
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public int updateWxUser(WxUser wxUser) {
        wxUser.setUpdateBy(SecurityUtils.getUsername());
        wxUser.setUpdateTime(DateUtils.getNowDate());
        return wxUserMapper.updateWxUser(wxUser);
    }

    @Override
    public int updateWxUserNoToken(WxUser wxUser) {
        wxUser.setUpdateBy("1");
        wxUser.setUpdateTime(DateUtils.getNowDate());
        return wxUserMapper.updateWxUser(wxUser);
    }

    /**
     * 批量删除微信用户
     *
     * @param ids 需要删除的微信用户ID
     * @return 结果
     */
    @Override
    public int deleteWxUserByIds(String[] ids) {
        return wxUserMapper.deleteWxUserByIds(ids);
    }

    /**
     * 删除微信用户信息
     *
     * @param id 微信用户ID
     * @return 结果
     */
    @Override
    public int deleteWxUserById(String id) {
        return wxUserMapper.deleteWxUserById(id);
    }

    /**
     * 批量逻辑删除微信用户
     *
     * @param ids 需要删除的微信用户ID
     * @return 结果
     */
    @Override
    public int logicDeleteWxUserByIds(String[] ids) {
        return wxUserMapper.logicDeleteWxUserByIds(ids);
    }

    /**
     * 逻辑删除微信用户信息
     *
     * @param id 微信用户ID
     * @return 结果
     */
    @Override
    public int logicDeleteWxUserById(String id) {
        return wxUserMapper.logicDeleteWxUserById(id);
    }

    @Override
    public WxUser getByOpenId(String openId) {
        return wxUserMapper.getByOpenId(openId);
    }


    /**
     * 新增微信用户
     *
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public int genWxUser(WxUser wxUser) {
        if(StringUtils.isBlank(wxUser.getId())){
            wxUser.setId(IdUtils.fastSimpleUUID());
        }
//        wxUser.setCreateBy(SecurityUtils.getUsername());
        wxUser.setCreateTime(DateUtils.getNowDate());
        return wxUserMapper.insertWxUser(wxUser);
    }

    /**
     * 修改微信用户
     * @param wxUser 微信用户
     * @return 结果
     */
    @Override
    public WxUser updateWxUserInfo(WxUser wxUser) {
        String id = SecurityUtils.getWxUserId();
        if(StringUtils.isNotBlank(id)){
            wxUser.setId(id);
            wxUser.setUpdateTime(DateUtils.getNowDate());
            updateWxUser(wxUser);
        }
        return wxUser;
    }

    @Override
    public Map<String, Object> bindSysUser(String userName, String password) {
        Map<String, Object> map = new HashMap<String, Object>();
        //首先判断userName和password的有效性
        SysUser user = sysUserService.selectUserByUserName(userName);
        if(user == null){
            map.put("flag", false);
            map.put("msg", "用户不存在！");
            return map;
        }
        boolean flag = SecurityUtils.matchesPassword(password, user.getPassword());
        if(flag){
            //将获取到sysUser的id绑定到wxUser上
            String id = SecurityUtils.getWxUserId();
            WxUser wxUser = selectWxUserById(id);
            wxUser.setUserId(user.getUserId());
            this.updateWxUser(wxUser);

            //更新登录时间
            user.setLoginDate(DateUtils.getNowDate());
            sysUserService.updateUserById(user);

            map.put("flag", true);
            map.put("msg", "绑定成功！");
            map.put("sysUser", user);

            //获取用户的角色
            List<SysRole> roles = roleService.selectRolesByUserIdWx(user.getUserId());
            user.setRoles(roles);
            //获取用户部门
            if(user.getDeptId() != null){
                SysDept dept = sysDeptService.selectDeptById(user.getDeptId());
                user.setDept(dept);
            }

            //刷新登录用户缓存
            LoginUser loginUser = SecurityUtils.getLoginUser();
            loginUser.setUser(user);
            loginUser.setWxUser(wxUser);

            //获取用户的权限 permissions
            Set<String> perms = new HashSet<String>();
            if(loginUser.getUser() != null){
                perms = getMenuPermission(loginUser.getUser());
                loginUser.setPermissions(getMenuPermission(loginUser.getUser()));
            }
            map.put("permissions", perms);

            if(loginUser.getWxUserId() != null){
                refreshWxUserToken(loginUser);
            }

        }else{
            map.put("flag", false);
            map.put("msg", "密码不匹配，请重新输入");
        }
        return map;
    }


    @Override
    public int unBindWxUser() {
        try {
            //获取当前登录用户
            LoginUser loginUser = SecurityUtils.getLoginUser();
            String wxUserId = loginUser.getWxUserId();
            int i = wxUserMapper.unBindWxUser(wxUserId);

            WxUser wxUser = this.selectWxUserById(wxUserId);

            //刷新用户缓存
            SysUser sysUser = new SysUser();
            sysUser.setUserName(wxUser.getNickName());
//            sysUser.setRoles(new ArrayList<>());
//            sysUser.setDept(new SysDept());
            loginUser.setUser(sysUser);
            loginUser.setWxUser(wxUser);

            refreshWxUserToken(loginUser);

            return i;
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }


    @Override
    public int unBindWxUser(String wxUserId) {
        try {
            return wxUserMapper.unBindWxUser(wxUserId);
        }catch (Exception e){
            e.printStackTrace();
        }
        return 0;
    }


    @Override
    public void refreshWxUserToken(LoginUser loginUser){
        // 根据wxUserId更新loginUser缓存
        loginUser.setLoginTime(System.currentTimeMillis());
        loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE);
        String wxUserKey = CacheConstants.LOGIN_TOKEN_KEY + loginUser.getWxUserId();
        redisCache.setCacheObject(wxUserKey, loginUser, expireTime, TimeUnit.MINUTES);
    }

    /**
     * 获取菜单数据权限
     * @param user 用户信息
     * @return 菜单权限信息
     */
    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
        }
        return perms;
    }


    @Override
    public int unBindWxUserByUserId(String userId){
        //删除微信用户绑定
        return wxUserMapper.unBindWxUserByUserId(userId);
    }


}
